package com.aigou.controller;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.aigou.exception.AigouException;
import com.aigou.pojo.Goods;
import com.aigou.pojo.Order;
import com.aigou.pojo.Result;
import com.aigou.service.GoodsService;
import com.aigou.service.IOrderService;
import com.aigou.utils.AiGouUtil;
import com.aigou.vo.SkillOrder;
import com.alibaba.fastjson2.JSON;

@RestController
@RequestMapping("/skill")
public class SkillController {

	@Autowired
	StringRedisTemplate redisTemplate;
	@Autowired
	GoodsService goodsService;
	@Autowired
	IOrderService orderService;
	@Autowired
	AiGouUtil aiGouUtil;
	@Autowired
	RabbitTemplate rabbitTemplate;

	@GetMapping("/goodsList")
	public Result goodsList() {
		Result result = new Result();

		Map<Object, Object> map = redisTemplate.opsForHash().entries("skill:goods:list");

		List<Goods> glist = map.values().stream().map((json) -> {
			return JSON.parseObject(json.toString(), Goods.class);
		}).map((g) -> {
			String numStr = redisTemplate.opsForValue().get("skill:goods:num:" + g.getId());
			g.setNum(Integer.valueOf(numStr));
			return g;
		}).collect(Collectors.toList());

		result.setData(glist);

		return result;
	}

	@GetMapping("/goods/{gid}")
	public Result goods(@PathVariable("gid") Integer gid) {
		Result result = new Result();

		Map<Object, Object> map = redisTemplate.opsForHash().entries("skill:goods:list");

		Goods goods = map.values().stream().map((json) -> {
			return JSON.parseObject(json.toString(), Goods.class);
		}).filter((g) -> g.getId().equals(gid)).map((g) -> {
			String numStr = redisTemplate.opsForValue().get("skill:goods:num:" + gid);
			g.setNum(Integer.valueOf(numStr));
			return g;
		}).findFirst().get();

		result.setData(goods);

		return result;
	}

	@GetMapping("/createOrder/{gid}")
	public Result createOrder(@PathVariable("gid") Integer gid) {

		String cGid = redisTemplate.opsForList().leftPop("skill:goods:" + gid);
		if (cGid == null) {
			throw new AigouException("秒杀失败");
		}

		Result result = new Result();
		Random r = new Random();
		Integer uid = r.nextInt(100);
		SkillOrder order = new SkillOrder();
		order.setGid(gid);
		order.setNum(1);
		order.setUid(uid);
		// 缓存中获取商品对象
		Goods goods = (Goods) goods(gid).getData();
		order.setPrice(goods.getSellPrice());

		Long cgNum = redisTemplate.opsForValue().decrement("skill:goods:num:" + gid);
		// 创建订单记录
		redisTemplate.opsForHash().put("skill:order", uid + ":" + gid, JSON.toJSONString(order));
		if (cgNum <= 0) {
			goods.setNum(0);
			// 减少秒杀商品数量
			redisTemplate.opsForHash().put("skill:goods:list", gid + "", JSON.toJSONString(goods));
			// 落地到mysql，清除缓存
			
			Map<Object, Object> entries = redisTemplate.opsForHash().entries("skill:order");
			Collection<Object> skillOrders = entries.values();
			skillOrders.forEach((orderStr) -> {
				
				SkillOrder tempSkillOrder = JSON.parseObject(orderStr.toString(), SkillOrder.class);
				
				// 写入mysql
				Order tempOrder = new Order();
				tempOrder.setUid(tempSkillOrder.getUid());
				tempOrder.setOrderSn(aiGouUtil.createOrderNum("MS"));
				tempOrder.setStatus(0);
				tempOrder.setPayStatus(0);
//				int intValue = tempSkillOrder.getPrice().multiply(new BigDecimal(100)).intValue();
//				tempOrder.setPriceChengjiao(intValue);
				tempOrder.setCreateTime(LocalDateTime.now());
				orderService.save(tempOrder);
			
				rabbitTemplate.convertAndSend("dle_queue", tempOrder.getId());
				
				try {
					TimeUnit.SECONDS.sleep(3);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			});
		}
		return result;
	}

	@GetMapping("/initGoods")
	public Result initGoodsToRedis() {
		Result result = new Result();

		ArrayList<Integer> ids = new ArrayList<>();
		ids.add(1);
		ids.add(2);
		ids.add(3);
		List<Goods> dbGoodslist = goodsService.findByIds(ids);
		dbGoodslist.forEach((g) -> {
			g.setNum(5);
			redisTemplate.opsForHash().put("skill:goods:list", g.getId() + "", JSON.toJSONString(g));

			Integer num = g.getNum();
			for (int i = 0; i < num; i++) {
				// 防止超卖
				redisTemplate.opsForList().leftPush("skill:goods:" + g.getId(), g.getId() + "");
			}

			// 库存扣减原子性
			redisTemplate.opsForValue().set("skill:goods:num:" + g.getId(), num + "");

		});
		return result;
	}

}
